////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package spark.skins.mobile
{
	import flash.events.Event;
	import flash.geom.Point;
	
	import mx.core.DPIClassification;
	import mx.core.mx_internal;
	
	import spark.components.Toast;
	import spark.components.supportClasses.StyleableTextField;
	import spark.filters.GlowFilter;
	import spark.skins.mobile.supportClasses.MobileSkin;
	
	/**
	 *  ActionScript-based skin for the Toast control. 
	 *  The colors of the component can
	 *  be customized using styles. This class is responsible for all of the
	 *  graphics drawing, with no additional fxg assets.
	 *  
	 *  @langversion 3.0
	 *  @playerversion AIR 3
	 *  @productversion Flex 4.6
	 *
	 *  @see spark.components.Toast
	 */    
	public class ToastSkin extends MobileSkin
	{
		
		//----------------------------------------------------------------------------------------------
		//
		//  Constructor
		//
		//----------------------------------------------------------------------------------------------
		/**
		 *  Constructor.
		 * 
		 *  @langversion 3.0
		 *  @playerversion AIR 3
		 *  @productversion Flex 4.6
		 **/
		public function ToastSkin()
		{
			super();
			
			switch (applicationDPI)
			{
				case DPIClassification.DPI_320:
				{
					layoutStrokeWeight = 4;
					layoutInnerVerticalPadding = 4;
					layoutInnerHorizontalPadding = 16;
					layoutOuterPadding = 40;
					layoutDropShadowStrength = 16;
					break;
				}
				case DPIClassification.DPI_240:
				{
					layoutStrokeWeight = 3;
					layoutInnerVerticalPadding = 3;
					layoutInnerHorizontalPadding = 12;
					layoutOuterPadding = 30;
					layoutDropShadowStrength = 12;
					break;
				}
				case DPIClassification.DPI_160:
				default:
				{
					layoutStrokeWeight = 2;
					layoutInnerVerticalPadding = 2;
					layoutInnerHorizontalPadding = 8;
					layoutOuterPadding = 20;
					layoutDropShadowStrength = 8;
					break;
				}
			}
			
			// Add our surrouding drop-shadow
			this.filters = [ new GlowFilter(0x000000, 1.0, layoutDropShadowStrength, layoutDropShadowStrength)];
		}
		
		
		//----------------------------------------------------------------------------------------------
		//
		//  Variables
		//
		//----------------------------------------------------------------------------------------------
		
		
		/**
		 *  The stroke weight outlining the graphics of the skin.
		 *
		 *  @langversion 3.0
		 *  @playerversion AIR 3
		 *  @productversion Flex 4.6
		 */
		protected var layoutStrokeWeight:Number;
		
		/**
		 *  The padding around the label
		 *
		 *  @langversion 3.0
		 *  @playerversion AIR 3
		 *  @productversion Flex 4.6
		 */
		protected var layoutInnerVerticalPadding:Number;
		
		/**
		 *  The padding around the label
		 *
		 *  @langversion 3.0
		 *  @playerversion AIR 3
		 *  @productversion Flex 4.6
		 */
		protected var layoutInnerHorizontalPadding:Number;
		
		/**
		 *  The padding between the contents and the edges of the parent
		 *
		 *  @langversion 3.0
		 *  @playerversion AIR 3
		 *  @productversion Flex 4.6
		 */
		protected var layoutOuterPadding:Number;
		
		/**
		 *  The distance to show the drop-shadow around the background box
		 *
		 *  @langversion 3.0
		 *  @playerversion AIR 3
		 *  @productversion Flex 4.6
		 */
		protected var layoutDropShadowStrength:Number = 8;
		
		/**
		 *  The label for the text in the notification box
		 * 	Exposed for styling purposes only.
		 *
		 *  @langversion 3.0
		 *  @playerversion AIR 3
		 *  @productversion Flex 4.6
		 */
		public var labelDisplay:StyleableTextField;
		
		
		//----------------------------------
		//  hostComponent
		//----------------------------------
		
		private var _hostComponent:Toast;
		
		/**
		 * @copy spark.skins.spark.ApplicationSkin#hostComponent
		 */
		public function get hostComponent():Toast
		{
			return _hostComponent;
		}
		
		/**
		 *  @private
		 */
		public function set hostComponent(value:Toast):void
		{
			if (_hostComponent === value)
				return;
			
			if (_hostComponent)
				_hostComponent.removeEventListener(Event.CHANGE, textChanged_handler);
			
			_hostComponent = value;
			
			if (_hostComponent)
				_hostComponent.addEventListener(Event.CHANGE, textChanged_handler);
		}
		
		//----------------------------------------------------------------------------------------------
		//
		//  Overridden Methods
		//
		//----------------------------------------------------------------------------------------------
		
		/**
		 *  @private
		 *  Redraw the graphics of the skin as necessary
		 */
		override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.drawBackground(unscaledWidth, unscaledHeight);
			
			graphics.clear();
			
			// get our styles
			var contentBackgroundColor:uint = getStyle("contentBackgroundColor");
			var contentBackgroundAlpha:Number = getStyle("contentBackgroundAlpha");
			var cornerRadius:Number = getStyle("cornerRadius");
			var strokeColor:uint = getStyle("strokeColor");
			var strokeAlpha:Number = getStyle("strokeAlpha");
			
			// calculate our size based on label dimensions and skin properties
			var calculatedWidth:Number = labelDisplay.textWidth + 2 * layoutInnerHorizontalPadding + 2 * layoutStrokeWeight;
			var calculatedHeight:Number = labelDisplay.height + 2 * layoutInnerVerticalPadding + 2 * layoutStrokeWeight;;
			
			var notificationParentGlobalPt:Point = _hostComponent.notificationParent.localToGlobal(new Point(0, 0));
			var posX:Number = notificationParentGlobalPt.x + (_hostComponent.notificationParent.width - calculatedWidth) / 2;
			var parentBottom:Number = notificationParentGlobalPt.y + _hostComponent.notificationParent.height;
			var posY:Number = parentBottom - calculatedHeight - layoutOuterPadding;
			
			// draw our notification box
			graphics.lineStyle(layoutStrokeWeight, strokeColor, strokeAlpha, true);
			graphics.beginFill(contentBackgroundColor, contentBackgroundAlpha);
			graphics.drawRoundRectComplex(posX, posY, calculatedWidth, calculatedHeight, cornerRadius, cornerRadius, cornerRadius, cornerRadius);
			graphics.endFill();
			graphics.lineStyle();
		}
		
		/**
		 *  @private
		 *  Resize and reposition as necessary
		 */
		override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.layoutContents(unscaledWidth, unscaledHeight);
			
			var notificationParentGlobalPt:Point = _hostComponent.notificationParent.localToGlobal(new Point(0, 0));
			
			var parentBottom:Number = notificationParentGlobalPt.y + _hostComponent.notificationParent.height;
			var posX:Number = notificationParentGlobalPt.x + layoutOuterPadding;
			var posY:Number = parentBottom - layoutOuterPadding - labelDisplay.height; 
			
			setElementPosition(labelDisplay, posX, posY);
		}
		
		
		/**
		 * @private
		 */
		override protected function createChildren():void
		{
			super.createChildren();
			
			labelDisplay = StyleableTextField(createInFontContext(StyleableTextField));
			labelDisplay.wordWrap = true;
			labelDisplay.multiline = true;
			labelDisplay.styleName = this;
			labelDisplay.setStyle("textAlign", "center");
			labelDisplay.commitStyles();
			
			// Set the max width of our label
			labelDisplay.width = _hostComponent.notificationParent.width - 2 * layoutOuterPadding;
			addChild(labelDisplay);
			
			labelDisplay.text = _hostComponent.label;
		}
		
		/**
		 *  @private
		 */
		override protected function measure():void
		{
			// update the label height
			var measuredTextSize:Point = labelDisplay.mx_internal::measuredTextSize;
			
			if (labelDisplay.height != measuredTextSize.y)
				labelDisplay.height = measuredTextSize.y;
		}
		
		//----------------------------------------------------------------------------------------------
		//
		//  Event Handlers
		//
		//----------------------------------------------------------------------------------------------
		
		/**
		 * When the label on the hostComponent changes, update the label and
		 * underlying background to reflect the new text.
		 */
		private function textChanged_handler(event:Event):void
		{
			if (_hostComponent)
				labelDisplay.text = _hostComponent.label;
			
			invalidateDisplayList();
			invalidateSize();
		}
		
	}
}
